//! 脚本执行上下文

use std::collections::HashMap;
use std::sync::Arc;
use serde::{Deserialize, Serialize};
use data_gateway_kernel::DataGatewayKernel;
use crate::ast::Value;
use crate::error::Result;

/// 脚本执行上下文
#[derive(Clone)]
pub struct ScriptContext {
    /// 变量存储
    variables: HashMap<String, Variable>,
    /// 函数存储
    functions: HashMap<String, Function>,
    /// 内核引用
    kernel: Option<Arc<DataGatewayKernel>>,
    /// 上下文配置
    config: ContextConfig,
}

/// 变量定义
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Variable {
    /// 变量名
    pub name: String,
    /// 变量值
    pub value: Value,
    /// 变量类型
    pub var_type: VariableType,
    /// 是否只读
    pub readonly: bool,
    /// 创建时间
    pub created_at: chrono::DateTime<chrono::Utc>,
}

/// 变量类型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum VariableType {
    /// 局部变量
    Local,
    /// 全局变量
    Global,
    /// 常量
    Constant,
    /// 环境变量
    Environment,
}

/// 函数定义
#[derive(Debug, Clone)]
pub struct Function {
    /// 函数名
    pub name: String,
    /// 参数列表
    pub parameters: Vec<String>,
    /// 函数体
    pub body: FunctionBody,
    /// 函数类型
    pub function_type: FunctionType,
}

/// 函数体
#[derive(Debug, Clone)]
pub enum FunctionBody {
    /// 脚本函数
    Script(Vec<crate::ast::Statement>),
    /// 内置函数
    Builtin(String), // 存储函数名而不是函数指针
    /// 外部函数
    External(ExternalFunction),
}

/// 函数类型
#[derive(Debug, Clone)]
pub enum FunctionType {
    /// 用户定义函数
    UserDefined,
    /// 内置函数
    Builtin,
    /// 系统函数
    System,
}

/// 外部函数
#[derive(Debug, Clone)]
pub struct ExternalFunction {
    /// 函数名
    pub name: String,
    /// 模块路径
    pub module_path: String,
    /// 函数签名
    pub signature: String,
}

/// 上下文配置
#[derive(Debug, Clone)]
pub struct ContextConfig {
    /// 最大变量数量
    pub max_variables: usize,
    /// 最大函数数量
    pub max_functions: usize,
    /// 是否允许全局变量
    pub allow_global_variables: bool,
    /// 是否允许外部函数调用
    pub allow_external_functions: bool,
    /// 执行超时时间（毫秒）
    pub execution_timeout_ms: u64,
}

impl Default for ContextConfig {
    fn default() -> Self {
        Self {
            max_variables: 1000,
            max_functions: 100,
            allow_global_variables: true,
            allow_external_functions: false,
            execution_timeout_ms: 30000, // 30秒
        }
    }
}

impl ScriptContext {
    /// 创建新的脚本上下文
    pub fn new() -> Self {
        let mut context = Self {
            variables: HashMap::new(),
            functions: HashMap::new(),
            kernel: None,
            config: ContextConfig::default(),
        };
        
        // 注册内置函数
        context.register_builtin_functions();
        
        context
    }
    
    /// 创建带内核的脚本上下文
    pub fn with_kernel(kernel: Arc<DataGatewayKernel>) -> Self {
        let mut context = Self::new();
        context.kernel = Some(kernel);
        context
    }
    
    /// 创建带配置的脚本上下文
    pub fn with_config(config: ContextConfig) -> Self {
        let mut context = Self::new();
        context.config = config;
        context
    }
    
    /// 设置变量
    pub fn set_variable(&mut self, name: String, value: Value) -> Result<()> {
        if self.variables.len() >= self.config.max_variables {
            return Err(anyhow::anyhow!("变量数量超出限制: {}", self.config.max_variables).into());
        }
        
        let variable = Variable {
            name: name.clone(),
            value,
            var_type: VariableType::Local,
            readonly: false,
            created_at: chrono::Utc::now(),
        };
        
        self.variables.insert(name, variable);
        Ok(())
    }
    
    /// 获取变量
    pub fn get_variable(&self, name: &str) -> Option<&Variable> {
        self.variables.get(name)
    }
    
    /// 获取变量值
    pub fn get_variable_value(&self, name: &str) -> Option<Value> {
        self.variables.get(name).map(|var| var.value.clone())
    }
    
    /// 设置全局变量
    pub fn set_global_variable(&mut self, name: String, value: Value) -> Result<()> {
        if !self.config.allow_global_variables {
            return Err(anyhow::anyhow!("不允许设置全局变量").into());
        }
        
        let variable = Variable {
            name: name.clone(),
            value,
            var_type: VariableType::Global,
            readonly: false,
            created_at: chrono::Utc::now(),
        };
        
        self.variables.insert(name, variable);
        Ok(())
    }
    
    /// 设置常量
    pub fn set_constant(&mut self, name: String, value: Value) -> Result<()> {
        let variable = Variable {
            name: name.clone(),
            value,
            var_type: VariableType::Constant,
            readonly: true,
            created_at: chrono::Utc::now(),
        };
        
        self.variables.insert(name, variable);
        Ok(())
    }
    
    /// 注册函数
    pub fn register_function(&mut self, function: Function) -> Result<()> {
        if self.functions.len() >= self.config.max_functions {
            return Err(anyhow::anyhow!("函数数量超出限制: {}", self.config.max_functions).into());
        }
        
        self.functions.insert(function.name.clone(), function);
        Ok(())
    }
    
    /// 获取函数
    pub fn get_function(&self, name: &str) -> Option<&Function> {
        self.functions.get(name)
    }
    
    /// 获取内核引用
    pub fn kernel(&self) -> Option<Arc<DataGatewayKernel>> {
        self.kernel.clone()
    }
    
    /// 获取配置
    pub fn config(&self) -> &ContextConfig {
        &self.config
    }
    
    /// 清空变量
    pub fn clear_variables(&mut self) {
        self.variables.clear();
    }
    
    /// 清空函数
    pub fn clear_functions(&mut self) {
        self.functions.clear();
        self.register_builtin_functions();
    }
    
    /// 获取所有变量
    pub fn get_all_variables(&self) -> &HashMap<String, Variable> {
        &self.variables
    }
    
    /// 获取所有函数
    pub fn get_all_functions(&self) -> &HashMap<String, Function> {
        &self.functions
    }
    
    /// 注册内置函数
    fn register_builtin_functions(&mut self) {
        // 数学函数
        self.register_builtin_function("abs", vec!["x".to_string()]);
        self.register_builtin_function("max", vec!["a".to_string(), "b".to_string()]);
        self.register_builtin_function("min", vec!["a".to_string(), "b".to_string()]);
        self.register_builtin_function("round", vec!["x".to_string()]);
        
        // 字符串函数
        self.register_builtin_function("len", vec!["s".to_string()]);
        self.register_builtin_function("upper", vec!["s".to_string()]);
        self.register_builtin_function("lower", vec!["s".to_string()]);
        self.register_builtin_function("trim", vec!["s".to_string()]);
        
        // 类型转换函数
        self.register_builtin_function("to_string", vec!["value".to_string()]);
        self.register_builtin_function("to_int", vec!["value".to_string()]);
        self.register_builtin_function("to_float", vec!["value".to_string()]);
        
        // 数组函数
        self.register_builtin_function("array_len", vec!["arr".to_string()]);
        self.register_builtin_function("array_push", vec!["arr".to_string(), "value".to_string()]);
        self.register_builtin_function("array_pop", vec!["arr".to_string()]);
        
        // 日期时间函数
        self.register_builtin_function("now", vec![]);
        self.register_builtin_function("format_date", vec!["date".to_string(), "format".to_string()]);
        
        // 工具函数
        self.register_builtin_function("print", vec!["value".to_string()]);
        self.register_builtin_function("debug", vec!["value".to_string()]);
    }
    
    /// 注册内置函数
    fn register_builtin_function(&mut self, name: &str, parameters: Vec<String>) {
        let function = Function {
            name: name.to_string(),
            parameters,
            body: FunctionBody::Builtin(name.to_string()),
            function_type: FunctionType::Builtin,
        };
        
        self.functions.insert(name.to_string(), function);
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_script_context_creation() {
        let context = ScriptContext::new();
        assert_eq!(context.variables.len(), 0);
        assert!(context.functions.len() > 0); // 应该有内置函数
        assert!(context.kernel.is_none());
    }
    
    #[test]
    fn test_variable_operations() {
        let mut context = ScriptContext::new();
        
        // 设置变量
        context.set_variable("x".to_string(), Value::Integer(42)).unwrap();
        
        // 获取变量
        let var = context.get_variable("x").unwrap();
        assert_eq!(var.name, "x");
        assert!(matches!(var.value, Value::Integer(42)));
        assert!(matches!(var.var_type, VariableType::Local));
        assert!(!var.readonly);
        
        // 获取变量值
        let value = context.get_variable_value("x").unwrap();
        assert!(matches!(value, Value::Integer(42)));
        
        // 不存在的变量
        assert!(context.get_variable("y").is_none());
        assert!(context.get_variable_value("y").is_none());
    }
    
    #[test]
    fn test_constant_operations() {
        let mut context = ScriptContext::new();
        
        // 设置常量
        context.set_constant("PI".to_string(), Value::Float(3.14159)).unwrap();
        
        let var = context.get_variable("PI").unwrap();
        assert!(matches!(var.var_type, VariableType::Constant));
        assert!(var.readonly);
    }
    
    #[test]
    fn test_builtin_functions() {
        let context = ScriptContext::new();
        
        // 检查内置函数
        assert!(context.get_function("abs").is_some());
        assert!(context.get_function("len").is_some());
        assert!(context.get_function("print").is_some());
        assert!(context.get_function("now").is_some());
        
        // 检查函数类型
        let abs_func = context.get_function("abs").unwrap();
        assert!(matches!(abs_func.function_type, FunctionType::Builtin));
        assert_eq!(abs_func.parameters.len(), 1);
        assert_eq!(abs_func.parameters[0], "x");
    }
    
    #[test]
    fn test_context_config() {
        let config = ContextConfig {
            max_variables: 10,
            max_functions: 5,
            allow_global_variables: false,
            allow_external_functions: true,
            execution_timeout_ms: 5000,
        };
        
        let context = ScriptContext::with_config(config);
        assert_eq!(context.config.max_variables, 10);
        assert_eq!(context.config.max_functions, 5);
        assert!(!context.config.allow_global_variables);
        assert!(context.config.allow_external_functions);
        assert_eq!(context.config.execution_timeout_ms, 5000);
    }
}
